/***************************************************************************
Name:		client.h
Autor:		Kevin Huber
Version:	0.4 Alpha
Last Edit:      12.06.2009

Beschreibung:
Diese Klasse stellt einen Clienten dar mit dem interagiert werden kann.
***************************************************************************/

#ifndef CLIENT_H
#define CLIENT_H

#include <string>
#include <QTcpSocket>
#include <QObject>
#include "tunnel_struckts.h"
#include "clientsocket.h"

enum Client_Status
{
    connecting,
    connected,
    disconnected,
    unknown,
    deleted
};

class ChatHandler;
class ClientManager;
class SQLConnection;
class Client : public QObject
{
    Q_OBJECT

public:
    Client(ClientManager *clientManager, unsigned int cId, QTcpSocket *socket, SQLConnection *nSQLConnection, Client_Status cStatus = unknown, QObject *parent = 0);
    ~Client();


/**********************************************************
 * Client attributes
 **********************************************************/
public:
    inline const quint32 &getId() const { return m_id; }
    inline const QString &getName() const { return ( m_nickname == "" ? m_loginName : m_nickname ); }
    inline const QString getPlayingGame() const { return isPlaying() ? m_gameName : ""; }
    inline const Client_Status &getStatus() const { return m_status; }
    inline const ChatHandler *getChatHandler() const { return m_chatHandler; }

    void setName(const QString &newName);
    void setPlayingGame(const QString &gName);
    inline void setId(quint32 nId) { m_id = nId; }

    inline void isNotPlaying()
    {
        m_playing = false;
        m_gameName = "";
    }
    inline const bool isPlaying() const { return m_playing; }

private:
    quint32       m_id;             // Client ID
    QString       m_loginName;      // Client loginName
    QString       m_nickname;       // Client Nickname <-- UNUSED!
    bool          m_playing;        // isPlaying()? <-- UNUSED!
    QString       m_gameName;       // if isPlaying() is true, this QString is filled with the name of the game :P <-- UNUSED!
    Client_Status m_status;         // Client status
    bool          m_firstUpdate;    // True until the client asks for his friendlist.

    ClientManager *m_clientManager;
    ChatHandler   *m_chatHandler;
    SQLConnection *m_TunnelDatabase;


/**********************************************************
 * Client list stuff
 **********************************************************/
public:
    inline Client *getNextClient() { return m_nextClient; }
    inline Client *getLastClient() { return m_lastClient; }
    inline Client *getClient(const quint32 &cId)
    {
        if( m_id == cId )
            return this;
        else if( !m_nextClient )
            return NULL;
        else
            return m_nextClient->getClient(cId);
    }
    inline Client *getClient(const QString &cName)
    {
        if( cName.compare(m_loginName) == 0 )
            return this;
        else if( !m_nextClient )
            return NULL;
        else
            return m_nextClient->getClient(cName);
    }
    inline void setNextClient(Client *nClient) { m_nextClient = nClient; }
    inline void setLastClient(Client *lClient) { m_lastClient = lClient; }

private:
    Client *m_nextClient;
    Client *m_lastClient;


/**********************************************************
 * ClientSocket relatet stuff
 **********************************************************/
public:
    inline ClientSocket* getSocket() { return m_socket; }

private:
    ClientSocket *m_socket;


/**********************************************************
 * Friends stuff
 **********************************************************/
public:
    void sendNotification_friendComesOnline(const QString &friend_loginName);

/**********************************************************
 * Client Operators
 **********************************************************/
public:
    // c1 == c2 ?
    bool operator==(const Client &c) { return m_id == c.getId(); }


/**********************************************************
 * Client Signals
 **********************************************************/
signals:
    void signal_disconnected(Client *client);
    void signal_newGlobalMessage(const QString &from, const QString &message);
    void signal_newPrivateMessage(const QString &from, const QString &message, const QString &to);
    void signal_goOffline(const QString &friend_loginName);


/**********************************************************
 * Client Slots
 **********************************************************/
private slots:
    void on_disconnected();
    void on_authCommand(const QString &arguments);
    void on_getFriendlist();
    void on_addFriend(const QString &arguments);
    void on_getFriendrequests();
    void on_acceptFriendInventation(const quint32 &applicant_uid);
    void emitNewGlobalMessage(const QString &Message);
    void emitNewPrivateMessage(const QString &Message, const QString &to);
    void on_friendGoesOffline(const QString &friend_loginName);
};

#endif // CLIENT_H
